package com.zhijian.medical.config;

import com.alibaba.fastjson.JSONObject;
import com.zhijian.medical.entity.dto.CellDto;
import com.zhijian.medical.entity.po.LocatorRecord;
import com.zhijian.medical.entity.po.MedicalDevice;
import com.zhijian.medical.entity.po.TemperatureRecord;
import com.zhijian.medical.service.impl.HarmfulServiceImpl;
import com.zhijian.medical.service.impl.LocatorRecordServiceImpl;
import com.zhijian.medical.service.impl.TemperatureRecordServiceImpl;
import com.zhijian.medical.util.CRCUtil;
import com.zhijian.medical.util.ConvertCode;
import com.zhijian.medical.util.LacUtil;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.nio.ByteBuffer;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
public class EchoServerHandler extends ChannelInboundHandlerAdapter {

    @Autowired
    private TemperatureRecordServiceImpl temperatureRecordService;

    @Autowired
    private LocatorRecordServiceImpl locatorRecordService;

    @Autowired
    private HarmfulServiceImpl harmfulService;


    private static EchoServerHandler echoServerHandler;


    @PostConstruct
    public void init() {
        echoServerHandler = this;
    }


    private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private String hex = "";

    private StringBuffer thingId = new StringBuffer();

    /*
     * channelAction
     *
     * channel 通道 action 活跃的
     *
     * 当客户端主动链接服务端的链接后，这个通道就是活跃的了。也就是客户端与服务端建立了通信通道并且可以传输数据
     *
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().localAddress().toString() + " 通道已激活！");
    }

    /*
     * channelInactive
     *
     * channel 通道 Inactive 不活跃的
     *
     * 当客户端主动断开服务端的链接后，这个通道就是不活跃的。也就是说客户端与服务端的关闭了通信通道并且不可以传输数据
     *
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().localAddress().toString() + " 通道不活跃！");
        // 关闭流

    }

//    /**
//     * @param buf
//     * @return
//     * @author dahua
//     * TODO  此处用来处理收到的数据中含有中文的时  出现乱码的问题
//     * 2017年8月31日 下午7:57:28
//     */
//    private String getMessage(ByteBuf buf) {
//        byte[] con = new byte[buf.readableBytes()];
//        buf.readBytes(con);
//        try {
//            return new String(con, "UTF-8");
//        } catch (UnsupportedEncodingException e) {
//            e.printStackTrace();
//            return null;
//        }
//    }

    /**
     * 功能：读取服务器发送过来的信息
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        try {
            ByteBuf buf = (ByteBuf) msg;
            //创建目标大小的数组
            byte[] barray = new byte[buf.readableBytes()];
            //把数据从bytebuf转移到byte[]
            buf.getBytes(0, barray);
            String str = hex(barray);
            hex = str;
            System.out.println("读取服务器发送过来的信息" + str);
            buf.release();
        } catch (Exception e){
            e.printStackTrace();
        }finally {

        }
    }


    public static String hex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte aByte : bytes) {
            result.append(String.format("%02x", aByte));
            // upper case
            // result.append(String.format("%02X", aByte));
        }
        return result.toString();
    }


    public static byte[] hexStrToByteArrs(String hexString) {
        if (StringUtils.isEmpty(hexString)) {
            return null;
        }

        hexString = hexString.replaceAll(" ", "");
        int len = hexString.length();
        int index = 0;

        byte[] bytes = new byte[len / 2];

        while (index < len) {
            String sub = hexString.substring(index, index + 2);
            bytes[index / 2] = (byte) Integer.parseInt(sub, 16);
            index += 2;
        }

        return bytes;
    }

    /**
     * 功能：读取完毕客户端发送过来的数据之后的操作
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

        // 第一种方法：写一个空的buf，并刷新写出区域。完成后关闭sock channel连接。
        try{
            String hex2 = "";

            StringBuilder crcStr = new StringBuilder();
            //状态包
            StringBuilder qsw = new StringBuilder();

            //原有状态包
            StringBuilder yy = new StringBuilder();
            qsw.append(hex.substring(0, 4));
            yy.append(hex.substring(0, 4));
            qsw.append("05");
            crcStr.append("05");

            yy.append("05");
            qsw.append(hex.substring(6, 8));
            crcStr.append(hex.substring(6, 8));
            yy.append(hex.substring(6, 8));

//        hex2 = "05" +hex.substring(6,12);
//
//        System.out.println("hex2:"+hex2);


            qsw.append(hex.substring(hex.length() - 12, hex.length() - 8));
            crcStr.append(hex.substring(hex.length() - 12, hex.length() - 8));
            yy.append(hex.substring(hex.length() - 12, hex.length() - 8));
            byte[] bytes = hexStrToByteArrs(crcStr.toString());

            String CRC = CRCUtil.CRC_16_X25(bytes);
            qsw.append(CRC);
            yy.append(hex.substring(hex.length() - 8, hex.length() - 4));
            qsw.append(hex.substring(hex.length() - 4, hex.length()));
            yy.append(hex.substring(hex.length() - 4, hex.length()));

//        String str = "78780A134401040001000508450D0A";

            if ("0b".equals(hex.substring(4, 6))) {

                String Str1 = hex.substring(16, 18);
                int xx = Integer.parseInt(Str1, 16);

                String str4 =  Integer.toBinaryString(xx);
                Double y = 0.0;
                if(str4.length()==8 && str4.substring(0,1).equals("1")){
                    y = getTemperature(hex);
                }else {
                    DecimalFormat df = new DecimalFormat("#####0.00");
                    String Str16 = hex.substring(16, 20);
                    Double x = Double.valueOf(Integer.parseInt(Str16, 16));
                    y = Double.valueOf(df.format(x/10));
                }
                TemperatureRecord temperature = new TemperatureRecord();
                temperature.setCreateTime(new Date());
                temperature.setTemperature(y);
                System.out.println("此时温度为：" + y);
                temperature.setPower(String.valueOf(Integer.parseInt(hex.substring(10, 12), 16)*16));
                temperature.setGsm(String.valueOf(Integer.parseInt(hex.substring(12, 14), 16)));
                temperature.setUpdateTime(new Date());
                temperature.setThingId(thingId.toString());
                echoServerHandler.temperatureRecordService.insert(temperature);
                System.out.println("服务段原本接收到消息：" + hex);

            }
            if ("24".equals(hex.substring(6, 8))) {
                JSONObject jt = getLACData(hex);
                LocatorRecord locator = new LocatorRecord();
                locator.setLat(jt.getString("lat"));
                locator.setLon(jt.getString("lon"));
                locator.setRadius(jt.getString("redius"));
                locator.setAddress(jt.getString("address"));
                locator.setCreateTime(new Date());
                locator.setThingId(thingId.toString());
                echoServerHandler.locatorRecordService.insert(locator);
                System.out.println("此数据是GPS定位数据");
            }

            if ("22".equals(hex.substring(6, 8))) {
                System.out.println("此数据是GPS定位数据");
            }

            if("01".equals(hex.substring(6, 8))){
                thingId = new StringBuffer();
                thingId.append(hex.substring(8, 10));
                thingId.append(hex.substring(10, 12));
                thingId.append(hex.substring(12, 14));
                thingId.append(hex.substring(14, 16));
                thingId.append(hex.substring(16, 18));
                thingId.append(hex.substring(18, 20));
                thingId.append(hex.substring(20, 22));
                thingId.append(hex.substring(22, 24));


            }
            if(!thingId.toString().equals("")){
                MedicalDevice medicalDevice = echoServerHandler.harmfulService.queryInfo(thingId.toString());
                if(medicalDevice ==null){
                    MedicalDevice medicalDevice1 = new MedicalDevice();
                    medicalDevice1.setDeviceId(thingId.toString());
                    medicalDevice1.setDeviceType("3");
                    medicalDevice1.setDeviceName("温度定位模块");
                    medicalDevice1.setStatus(1);
                    medicalDevice1.setCreateTime(new Date());
                    medicalDevice1.setUpdateTime(new Date());
                    echoServerHandler.harmfulService.saveMedical(medicalDevice1);
                }
            }

            writeMessage(ctx, qsw.toString());
        }catch (Exception e){
            e.printStackTrace();
            writeMessage(ctx, "");
        }


//        writeMessage(ctx,getHexBytes(str));
//        ctx.writeAndFlush().addListener(ChannelFutureListener.CLOSE);
    }

    /**
     * 解析定位数据
     *
     * @param hex
     */
    public JSONObject getLACData(String hex) {
        String year = "20" + String.valueOf(Integer.parseInt(hex.substring(8, 10), 16));
        String month = String.valueOf(Integer.parseInt(hex.substring(10, 12), 16));
        String day = String.valueOf(Integer.parseInt(hex.substring(12, 14), 16));
        String hour = String.valueOf(Integer.parseInt(hex.substring(14, 16), 16) + 8);
        String min = String.valueOf(Integer.parseInt(hex.substring(16, 18), 16));
        String sec = String.valueOf(Integer.parseInt(hex.substring(18, 20), 16));


        int mcc = Integer.parseInt(hex.substring(22, 26), 16);
        int mnc = Integer.parseInt(hex.substring(26, 28), 16);




        int lac1 = Integer.parseInt(hex.substring(30, 34), 16);
        int ci1 = Integer.parseInt(hex.substring(34, 40), 16);

        int lac2 = Integer.parseInt(hex.substring(42, 46), 16);
        int ci2 = Integer.parseInt(hex.substring(46, 52), 16);


        int lac3 = Integer.parseInt(hex.substring(54, 58), 16);
        int ci3 = Integer.parseInt(hex.substring(58, 64), 16);

        int lac4 = Integer.parseInt(hex.substring(66, 70), 16);
        int ci4 = Integer.parseInt(hex.substring(70, 76), 16);

        CellDto cellDto = new CellDto();
        cellDto.setMnc(mnc);
        cellDto.setMcc(mcc);
        cellDto.setLac(lac1);
        cellDto.setCi(ci1);

        JSONObject json = LacUtil.MapToJson(cellDto);
        return json;
    }

    public static byte[] getHexBytes(String str) {
        str = str.replaceAll(" ", "");
        byte[] bytes = new byte[str.length() / 2];
        for (int i = 0; i < str.length() / 2; i++) {
            String subStr = str.substring(i * 2, i * 2 + 2);
            bytes[i] = (byte) Integer.parseInt(subStr, 16);
        }
        return bytes;
    }


    /*
      obj：byte数组
    */

    public void writeMessage(ChannelHandlerContext ctx, String receiveStr) {

        ByteBuf bufff = Unpooled.buffer();//netty需要用ByteBuf传输
        bufff.writeBytes(ConvertCode.hexString2Bytes(receiveStr));//对接需要16进制

        ctx.writeAndFlush(bufff);
        System.out.println("回写完毕...");

    }


    /**
     * 功能：服务端发生异常的操作
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
        System.out.println("异常信息：\r\n" + cause.getMessage());
    }


    /**
     * 将16进制转换为二进制
     *
     * @param hexString
     * @return
     */
    public static String hexString2binaryString(String hexString) {
        //16进制转10进制
        BigInteger sint = new BigInteger(hexString, 16);
        //10进制转2进制
        String result = sint.toString(2);
        //字符串反转
        return new StringBuilder(result).reverse().toString();
    }

    public static int NumberOf1(int n) {
        int count = 0;
        while(n != 0){
            count++;
            n = n & (n - 1);
        }
        return count;
    }


    public static Double getTemperature(String str){
        //得到16进制
        String Str16 = str.substring(16, 20);

        //得到2进制
        int sint=Integer.valueOf(Str16, 16);
        //得到10进制
        String str4 =  Integer.toBinaryString(sint);
        //减1
        int jf = Integer.parseInt(str4,2)-1;
        //得到2进制
        String str3 =  Integer.toBinaryString(jf);

        StringBuffer stringBuffer = new StringBuffer();
        for(int i=1;i<str3.length();i++){
            if(str3.substring(i,i+1).equals("1")){
                stringBuffer.append("0");
            }else{
                stringBuffer.append("1");
            }

        }

        DecimalFormat df = new DecimalFormat("#####0.00");

        Double d = Double.valueOf(Integer.parseInt(stringBuffer.toString(),2));
        return -Double.valueOf(df.format(d / 10));
    }



}
